package com.tansun.easycare.rule.common.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.tansun.easycare.rule.datamodel.entity.RuleDataparams;
import com.tansun.easycare.rule.datamodel.service.RuleDataparamsService;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.drools.core.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.tansun.easycare.rule.common.DataParamTreeVO;
import com.tansun.easycare.rule.common.JsonMessage;
import com.tansun.easycare.rule.common.ReferenceModel;
import com.tansun.easycare.rule.common.RuleBaseController;
import com.tansun.easycare.rule.common.model.Domain;
import com.tansun.easycare.rule.common.model.ResponseVO;
import com.tansun.easycare.rule.common.model.VersionCompareData;
import com.tansun.easycare.rule.common.model.VersionModel;
import com.tansun.easycare.rule.common.service.DataBomService;
import com.tansun.easycare.rule.common.web.model.ProjectInfo;
import com.tansun.easycare.rule.common.web.model.RuleVersionInfo;
import com.tansun.easycare.rule.datacomponent.service.IDataComponentService;
import com.tansun.easycare.rule.datamodel.entity.RuleDataDomain;
import com.tansun.easycare.rule.decisiontree.service.DecisionTreeService;
import com.tansun.easycare.rule.policytree.model.PolicyTreeVO;
import com.tansun.easycare.rule.policytree.service.PolicyTreeService;
import com.tansun.easycare.rule.ruleflow.model.RuleFlowModel;
import com.tansun.easycare.rule.ruleflow.service.RuleFlowRectsService;
import com.tansun.easycare.rule.ruleflow.service.RuleFlowService;
import com.tansun.easycare.rule.rulegroup.entity.RuleGroup;
import com.tansun.easycare.rule.rulegroup.service.RuleGroupRefService;
import com.tansun.easycare.rule.rulegroup.service.RuleGroupService;
import com.tansun.easycare.rule.rulemange.entity.RuleManage;
import com.tansun.easycare.rule.rulemange.service.RuleManageService;
import com.tansun.easycare.rule.ruleversion.service.RuleVersioninfoService;
import com.tansun.easycare.rule.scoremodel.model.ScoreEntity;
import com.tansun.easycare.rule.scoremodel.service.ScoreModelService;
import com.tansun.rule.common.RuleModelTypeEnum;
import com.tansun.rule.utils.LoggerManager;

/**
 * 公用控制信息
 *
 * @author lph
 */
@RestController
@RequestMapping(value = "/ruleProj/public")
public class PublicAction extends RuleBaseController {
    private static final Logger logger = LoggerFactory.getLogger(PublicAction.class);

    @Autowired
    private RuleVersioninfoService ruleVersioninfoService;
    @Autowired
    private RuleFlowRectsService ruleFlowRectsService;
    @Autowired
    private RuleFlowService ruleFlowService;
    @Autowired
    private DataBomService dataBomService;
    @Autowired
    private DecisionTreeService decisionTreeService;
    @Autowired
    private PolicyTreeService policyTreeService;
    @Autowired
    private RuleManageService ruleManageService;
    @Autowired
    private IDataComponentService dataComponentService;
    @Autowired
    private RuleGroupService ruleGroupService;
    @Autowired
    private RuleGroupRefService ruleGroupRefService;

    @Autowired
    private ScoreModelService scoreModelService;
    @Autowired
    private RuleDataparamsService ruleDataparamsService;
    /**
     * 规则模型归档
     */
    @RequestMapping("archiveFile")
    public @ResponseBody JsonMessage archiveFile(String code, String type, @RequestParam("verArr[]") List<String> verArr) {
        JsonMessage ret = new JsonMessage();
        return ret;
    }

    /**
     * 获取版本信息
     */
    @RequestMapping("getVersionInfo")
    public ResponseVO getVersionInfo(@RequestBody RuleVersionInfo ruleVerInfo) throws Exception {
    	ResponseVO ret = new ResponseVO();
        try {
            String projectCode =  ruleVerInfo.getProjectCode();
            List<VersionModel> verList = null;
        	if(RuleModelTypeEnum.GeneralRule.code.equals(ruleVerInfo.getType())) {
        		verList = this.ruleVersioninfoService.findVersionModelList(projectCode, ruleVerInfo.getType(), ruleVerInfo.getIndexCode());
        	}else {
	            Map<String, Object> map = new HashMap<String, Object>();
	            map.put("code", ruleVerInfo.getIndexCode());
	            map.put("projectCode", projectCode);
	            verList = this.ruleVersioninfoService.findVersionModelList(map);
        	}
        	if (verList != null && verList.size() > 0) {
                ret.setData(verList);
            }
        } catch (Exception e) {
            LoggerManager.error("", e, this.getClass());
            ret.setStatus(ResponseVO.ERROR);
            ret.setDescription("查找版本信息异常，请检查日志");
        }
        return ret;
    }

    /**
     * 公式试算
     *
     * @param formualStr 公式字符串
     * @param data       公式需要的参数数据，数据格式：{"cust_info":{"annual_income":"12"}}
     */
    @RequestMapping("calcFormual")
    public @ResponseBody
    JsonMessage calcFormual(String formualStr, String data) {
        JsonMessage ret = new JsonMessage();
        return ret;
    }

    @RequestMapping("ruleHelp")
    public String ruleHelp(String modelType) {
        return "ruleHelp/" + modelType;
    }
    /**
     * 获取版本信息
     */
    @RequestMapping("showReference")
    public String showReference(HttpServletRequest request, ModelMap map) throws Exception {
        String code = request.getParameter("code") == null ? "" : request.getParameter("code");
        List<ReferenceModel> referenceList = ruleFlowRectsService.findListByModelCode(code,getCurrProjectCode());
        map.addAttribute("referenceList", referenceList);
        return "rule/ruleproj/reference";
    }

    @RequestMapping("showCompare")
    public String showCompare(String id, String baseVer, String nextVer, String type,String rankRelationId, ModelMap map) throws Exception {
        map.put("id", id);
        map.put("baseVer", baseVer);
        map.put("nextVer", nextVer);
        map.put("type", type);
        map.put("rankRelationId", rankRelationId);
        if("policyRuleGroup".equals(type)) {
        	getRuleGroupInfo(map,id,baseVer,nextVer);
        	return "rule/rulegroup/ruleset/ruleGroupCompareList";
        }else {
        	return "rule/ruleproj/verionCompare";	
        }
    }
    /**
     * 规则集比较
     * @param request
     * @param response
     * @param map
     * @param baseId
     * @param nextId
     * @return
     * @throws Exception
     */
    @RequestMapping("rulegroupCompare")
    public String rulegroupCompare(HttpServletRequest request, HttpServletResponse response, ModelMap map,String baseId,String nextId) throws Exception {
        RuleGroup baserv = this.ruleGroupService.get(baseId);
        RuleGroup nextrv = this.ruleGroupService.get(nextId);
        map.put("manageid", baserv.getManageId());
        map.put("baserv", baserv);
        map.put("nextrv", nextrv);
        map.put("projectCode", this.getCurrProjectCode());
        return "rule/rulegroup/ruleset/ruleGroupCompare";
    }
    
    private void getRuleGroupInfo(ModelMap map,String id, String baseVer, String nextVer) throws Exception {
        RuleGroup condition = new RuleGroup();
        condition.setManageId(id);
        condition.setVersion(baseVer);
        List<RuleGroup> baseList = this.ruleGroupRefService.findRuleGroupList(condition);
        Map<String,RuleGroup> baseMap = new HashMap<String,RuleGroup>();
    	for (RuleGroup ruleGroup : baseList) {
            baseMap.put(ruleGroup.getGroupCode(), ruleGroup);
		}
        condition.setVersion(nextVer);
        List<RuleGroup> nextList = this.ruleGroupRefService.findRuleGroupList(condition);
        for (RuleGroup ruleGroup : nextList) {
            if(baseMap.containsKey(ruleGroup.getGroupCode())) {
            	RuleGroup base = baseMap.get(ruleGroup.getGroupCode());
            	if(!ruleGroup.getEvals().equals(base.getEvals()) 
            			|| !ruleGroup.getFacts().equals(base.getFacts()) 
            			|| !ruleGroup.getActions().equals(base.getActions())) {
            		base.setStatus("diff");
            		ruleGroup.setStatus("diff");
            	}else {
            		base.setStatus("same");
            		ruleGroup.setStatus("same");
            	}
            }else {
            	ruleGroup.setStatus("new");
            }
		}
        for (RuleGroup ruleGroup : baseList) {
        	if(StringUtils.isEmpty(ruleGroup.getStatus())) {
        		ruleGroup.setStatus("delete");
        	}
        }
        map.put("base", baseList);
        map.put("next", nextList);
    }
    @RequestMapping("compareContent1")
    public ResponseVO compareContent1(String id, String version, String type, String versionType, String rankRelationId,ModelMap map)
            throws Exception {
    	ResponseVO  res  = new ResponseVO();
    	ProjectInfo  projectInfo  = new ProjectInfo();
        map.put("id", id);
        map.put("version", version);
        map.put("versionType", versionType);
        map.put("type", type);
        map.put("rankRelationId", rankRelationId);
        if ("ruleFlow".equals(type)) {
            RuleFlowModel condition = new RuleFlowModel();
            condition.setManageId(id);
            condition.setProjectCode(this.getCurrProjectCode());
            condition.setVersion(version);
           // ruleFlowService.getRuleFlowData(condition, map);
        } else if ("decisionTree".equals(type)) {
            res.setData(decisionTreeService.getTreeInfo(id, version,null,null));
        } else if ("policyTree".equals(type)) {
            PolicyTreeVO policyTreeVO = this.policyTreeService.getTreeInfo(id, version);
            map.put("tree", policyTreeVO.getTree());
            map.put("version", policyTreeVO.getVersion());
            map.put("treeHtml", policyTreeVO.getTreeHtml());
            map.put("optionHtml", policyTreeVO.getOptionHtml());
            map.put("actionDatas", policyTreeVO.getActionDatas());
        }
        return res;
    }
    
    @RequestMapping("compareContent")
    public ResponseVO compareContent(@RequestBody VersionCompareData versionCompareData) throws Exception {
    	ResponseVO res = new ResponseVO();
    	String manageId = versionCompareData.getId();
    	String baseVer = versionCompareData.getBaseVer();
    	String nextVer = versionCompareData.getNextVer();
        RuleManage model = this.ruleManageService.getById(manageId);
        model.setVersion(baseVer);
    	//判断是否为评分模型
    	if(RuleModelTypeEnum.ScoreModel.desc.equalsIgnoreCase(versionCompareData.getType())) {
            ScoreEntity baseEntity = new ScoreEntity();
            baseEntity.setIndexModel(model);
            baseEntity.setTreeList(this.scoreModelService.getScoreItems(manageId, baseVer));
            versionCompareData.setBaseScoreEntity(baseEntity);
            
            
            RuleManage nextModel = (RuleManage)BeanUtils.cloneBean(model);
            nextModel.setVersion(nextVer);
            ScoreEntity nextEntity = new ScoreEntity();
            nextEntity.setIndexModel(nextModel);
            nextEntity.setTreeList(this.scoreModelService.getScoreItems(manageId, nextVer));
            versionCompareData.setNextScoreEntity(nextEntity);
    	}
    	res.setData(versionCompareData);
    	return res;
    }
    /**
     * 获取变量参数
     *
     * @return 返回是否成功对象，成功则包含变量信息
     */
    @RequestMapping("getParameter")
    public  ResponseVO getParameter(@RequestBody  ProjectInfo  projectInfo) throws Exception {
    	ResponseVO ret = new ResponseVO();
        try {
            List<DataParamTreeVO> resultList = dataBomService.findDataParam(projectInfo.getProjectCode(),projectInfo.getRankRelationId(),projectInfo.getSelected());
            ret.setData( resultList);
        } catch (Exception e) {
        	String error = ExceptionUtils.getStackTrace(e);
        	logger.error(error);
            ret.setStatus(ResponseVO.ERROR);
            ret.setDescription("获取数据模型变量失败");
        }
        return ret;
    }
    
    
    
    @RequestMapping("findDatasetList")
    public  ResponseVO  findDatasetList(@RequestBody  ProjectInfo  projectInfo) {
    	ResponseVO ret = new ResponseVO();
        try {
            List<DataParamTreeVO> resultList =this.dataBomService.findDatasetList(projectInfo);
            List<DataParamTreeVO> newResultList = new ArrayList<>();
            if(resultList!=null && resultList.size()>0){//过滤内置变量和函数变量
                for(DataParamTreeVO dataParamTreeVO : resultList){
                    if(dataParamTreeVO.getNameEN().equals("func")||dataParamTreeVO.getNameEN().equals("builtinParam")){
                      continue;
                    }
                    newResultList.add(dataParamTreeVO);
                }
            }
            ret.setData( newResultList);
        }catch(Exception e) {
        	String error = ExceptionUtils.getStackTrace(e);
        	logger.error(error);
            ret.setStatus(ResponseVO.ERROR);
            ret.setDescription("获取数据模型变量失败");
        }
        return ret;
        
    }

    /**
     * 获取Domain下拉选项
     *
     * @return 返回是否成功对象，成功则返回变量的离散值信息
     */
    @RequestMapping("getAttribute")
    public ResponseVO getAttribute(HttpServletRequest request,@RequestBody ProjectInfo projectInfo) throws Exception {
    	ResponseVO ret = new ResponseVO();
        try {

            Map<String, Domain> map = this.dataBomService.findDomainByProjectCode(projectInfo.getProjectCode());
            String attrs = JSON.toJSONString(map);
            ret.setData(attrs);
        } catch (Exception e) {
        	String error = ExceptionUtils.getStackTrace(e);
        	logger.error(error);
            ret.setStatus(ResponseVO.ERROR);
            ret.setDescription("获取数据模型枚举失败");
        }
        return ret;
    }

    @RequestMapping("getDomainItem")
    @ResponseBody
    public List<RuleDataDomain> findDataDomains(String domain, String projectCode) {
        return this.dataBomService.findDataDomains(domain);
    }

    @RequestMapping("getDataFromGate")
    public @ResponseBody
    JsonMessage getDataFromGate() {
        JsonMessage ret = new JsonMessage();
        try {
            String data = dataComponentService.getDataFromGate();
            ret.setData(data);
        } catch (Exception e) {
            ret.setMessage(e.getMessage());
            ret.setResult(false);
        }
        return ret;
    }
    
    @RequestMapping("getRuleManage")
    public  ResponseVO getRuleManage(@RequestBody ProjectInfo projectInfo) throws Exception {
    	ResponseVO ret = new ResponseVO();
        try {
            if(RuleModelTypeEnum.FunctionParam.code.equals(projectInfo.getModelType())){//函数变量
                  String name = projectInfo.getCode().split("_")[1];
                  String projectCode = projectInfo.getProjectCode();
                  RuleDataparams ruleDataparams = new RuleDataparams();
                  ruleDataparams.setName(name);
                  ruleDataparams.setProjectcode(projectCode);
                List<RuleDataparams> list = ruleDataparamsService.findList(ruleDataparams);
                ret.setData(list.get(0));
            }else{
                RuleManage ruleManage = null;
                if (!com.tansun.rule.utils.StringUtils.isEmpty(projectInfo.getCode())) {
                    ruleManage = ruleManageService.findByCode(projectInfo.getCode(), projectInfo.getProjectCode());
                }
                if (ruleManage == null) {
                    ruleManage=	ruleManageService.get(projectInfo.getManageId());
                }
                ret.setData(ruleManage);
            }
        } catch (Exception e) {
        	String error = ExceptionUtils.getStackTrace(e);
        	logger.error(error);
            ret.setStatus(ResponseVO.ERROR);
            ret.setDescription("获取数据模型失败");
        }
        return ret;
    }
    
    @RequestMapping("clearVersion")
    public  ResponseVO  clearVersion(@RequestBody RuleVersionInfo projectInfo) throws Exception {
    	ResponseVO ret = new ResponseVO();
        try {
        
        	RuleManage ruleManage = ruleManageService.findByCode(projectInfo.getIndexCode(), projectInfo.getProjectCode());
        	ruleManageService.clearVersion(ruleManage, projectInfo.getVerArr());
        } catch (Exception e) {
            LoggerManager.error("", e, this.getClass());
            ret.setStatus(ResponseVO.ERROR);
            ret.setDescription(e.getMessage());
        } 
        return ret;
    }
}
